package demo;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import demo.EnvMovingObject;

import pathAlgorithms.GraphLogger;
import robot.RoboLogger;
import simbad.gui.Simbad;

public class MainMovingObject {
	
	public static List<GraphLogger> graphLoggers;
	public static String fileName;;
	
	public static void main(String[] args) {
	 
		EnvMovingObject env = new EnvMovingObject();
		Simbad frame;
		graphLoggers = new ArrayList<GraphLogger>();
		
		
		List<String> argsList = new ArrayList<String> ();
		for (String str : args) {
			argsList.add(str);
		}
		try {
			if(args.length == 0)
			{
				env.addBoxes(0);
				frame = new Simbad(env,false);
			}
			else if (args.length == 2) {
				
				String fst = argsList.get(0);
				String fileName = argsList.get(1);
				
				if(fst.equals("-n"))
					env.writeRandomMapToFile(fileName, 0.33, 21,21);
				else {
					printHelp();
					System.exit(0);
				}
			}
			else if (args.length == 3) {
				fileName = args[2];
				String fst = argsList.get(0);
				String fileName = argsList.get(1);

				if(fst.equals("-l")) {
					env.readMap(fileName, 10, 10);
					frame = new Simbad(env,false);
				}
				else {
					printHelp();
					System.exit(0);
				}
			}
			else {
				printHelp();
				System.exit(0);
			}
		}
		catch (FileNotFoundException e)
		{
			System.out.println("Given file not found!\n");
			printHelp();
			System.exit(0);
		}
		catch (IOException e)
		{
			System.out.println(e.getMessage());
			System.exit(1);
		}
	}
	
	public static void printHelp() {
		System.out.println("Usage:");
		System.out.println("-n 'filepath': creates a new random generated map with given filepath.");
		System.out.println("-l 'filepath': load and run in the environment specified by given filepath.");

		System.out.println("If no arguments are given, runs a predefined environment.");
	}
	
	public static void generateMaps() {
		FileOutputStream fos = null;
		ObjectOutputStream out = null;
		try
		{
			for (int i = 0; i < 10; i++)
			{
				fos = new FileOutputStream("env" + i);
				out = new ObjectOutputStream(fos);
				out.writeObject(new EnvMovingObject());
				out.close();
			}
		}
		catch(IOException ex)
		{
			ex.printStackTrace();
		}
	}
	
	public static void finishRun(RoboLogger roboLogger,String RobotName) {
		try {
			FileWriter fw = new FileWriter(new File(fileName));
			fw.write(RobotName+"\n");
			fw.write("Distance traveled: "+ roboLogger.distanceTraveled+"\n");
			fw.write("Paths calculated: "+roboLogger.pathsCalculated+"\n");
			fw.write("Total targets in path: "+roboLogger.path.size()+"\n");
			fw.write("------------------------------\n");
			
			fw.write("Graph calculations:\n");
			fw.write("------------------------------\n");
			fw.write("Total:\n");
			fw.write("\n");
			int iterations = 0;
			int nodesCreated = 0;
			int nodesVisited = 0;
			int pathsCreated = 0;
			int pathsAdded = 0;
			int pathsPoped = 0;
			
			for(GraphLogger g: graphLoggers) {
				iterations += g.iterationsInLoop;
				nodesCreated += g.nodesCreated;
				nodesVisited += g.nodesVisited;
				pathsCreated += g.pathsCreated;
				pathsAdded += g.pathsAddedToQue;
				pathsPoped += g.pathsPopedFromQueue;
			}
			
	
			fw.write("Iterations: " +iterations+"\nNodes created: "+nodesCreated+"\nNodes visited: "+nodesVisited+
			           "\nPaths created: "+pathsCreated+"\nPaths added to queue: "+pathsAdded+"\nPaths poped from queue: "+pathsPoped+"\n");
			fw.write("------------------------------\n");
			
			
			fw.write("------------------------------\n");
			fw.write("Average per calculation: \n\n");
			
			double AvIterations   = (double)iterations / graphLoggers.size();
			double AvNodesCreated = (double)nodesCreated / graphLoggers.size();
			double AvNodesVisited = (double)nodesVisited / graphLoggers.size();
			double AvPathsCreated = (double)pathsCreated / graphLoggers.size();
			double AvPathsAdded   = (double)pathsAdded / graphLoggers.size();
			double AvPathsPoped   =(double)pathsPoped / graphLoggers.size();
			
			fw.write("Iterations: " +AvIterations+"\nNodes created: "+AvNodesCreated+"\nNodes visited: "+AvNodesVisited+
			           "\nPaths created: "+AvPathsCreated+"\nPaths added to queue: "+AvPathsAdded+"\nPaths poped from queue: "+AvPathsPoped+"\n");		
			fw.write("------------------------------\n");
			fw.write("------------------------------\n");
			fw.write("------------------------------\n");
			
			
			for(int i = 0; i < graphLoggers.size(); i++) {
				GraphLogger g = graphLoggers.get(i);
				fw.write("Path number "+i+":\n");
				fw.write("Iterations: " +g.iterationsInLoop+"\nNodes created: "+g.nodesCreated+"\nNodes visited: "+g.nodesVisited+
						           "\nPaths created: "+g.pathsAddedToQue+"\nPaths added to queue: "+g.pathsAddedToQue+"\nPaths poped from queue: "+g.pathsPopedFromQueue+"\n");
				fw.write("------------------------------\n");
			}
			
			fw.close();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {

		}
	}
	
}
